Satan3.1勒索病毒文件解密(附解密程序源码和病毒样本)
Satan病毒被揭密似乎已经不是一个秘密了,很多厂商包括瑞星,360,腾讯等公司相继推出了解密的工具。让还是小白的我有了很大的兴趣。于是查看他们的分析报告,病毒,其实仅仅是能对一款或者指定的几款进行解密。原因很简单,使用的对称加密密钥,而且能够找到并重组。有了密钥再解密就不是很难了。自己写了个程序用来专门解密Satan3.1病毒。该病毒的特性是在加密文件的后尾会加上HardwareID和Public两个数值,使用的是RC4加密。把源码发出来和大家分享下,小弟C写的很烂,大神勿喷。
Satan病毒加密
为了加快加密的速度加密方式为如下两种:
1、小于等于100000000字节
(1)特殊后缀,完全加密。
(2)其它后缀,部分加密,加密大小的算法 CryptSize = (FileSize / 2000) *1000,约为文件的二分之一。
举个例子,文件小于等于100000000字节时,zip格式的压缩包就会被完全加密,而RAR格式的只会被加密大约二分之一,因为zip是病毒指定的特殊后缀,而RAR不在列表中。
2、大于100000000 字节的文件
(1)特殊后缀,完全加密。
(2)其它后缀,部分加密,加密大小的算法 CryptSize = (FileSize / 5000) *1000,约为文件的五分之一。
举个例子,文件大于100000000字节时,zip格式的压缩包就会被完全加密,而RAR格式的 只会被加密大约五分之一,因为zip是病毒指定的特殊后缀,而RAR不在列表中。
特殊后缀包括:
sql, zip, php, asp, jsp, cpp, ini, aspx, cs, py, h, vbs, bat, conf, sh, inc, e, c, pl, csv, asm, doc, docx, xls, xlsx, ppt 这些后缀没有
以下后缀不会被加密:
Dbger, cab, pol, dll, msi, exe, lib, iso, bin, tmp, log, ocx, chm, dat, sys, dic, myd, sdi, lnk, gho, pbk
Satan病毒CryptAPI进行加密,加密的算法是RC,密钥结构如下:
[HardWareID]+k_str1+k_str2+k_str3+[PUBLIC]
k_str1, k_str2, k_str3都是硬编在程序当中的:
k_str1 = “dfsa#@FGDS!dsaKJiewiu*#&*))__=22121kD()@#(*#@#@!DSKL909*(!#!@AA”
k_str2 = “*@#AdJJMLDML#SXAIO98390d&th2nfd%%u2j312&&dsjdAa”
k_str3 = “@!FS#@DSKkop()(290#0^^^2920-((__!#*$gf4SAddAA”
Public的大小是0x20,病毒每次加密一个文件时候会生成一个,HardWareID和PUBLIC都会生成在文件的末尾:
Satan病毒加密过程:
MD5算法哈希密钥,加密算法为RC4
参考自:全新“撒旦”Satan勒索病毒来袭 瑞星独家提供解密工具
Satan病毒解密:
由于使用的是RC4对称加密的算法,所以解密也就很简单了,唯一不同的地方就是将CryptEncrypt函数更改为CryptDecrypt。其次就是对于不同的后缀要知道被加密文件加密内容的大小。本人写的程序是需要手动输入选择是解密全文件,半个文件或者是五分之一文件:
对被半加密的文件进行解密:
对全加密的文件进行解密:
解密函数代码:
int SatanDecrypt(char* HardWareID, char* Public, char* OutPutFileName, char* tmpFile, int count)
{
FILE *ptrFile1 = NULL;
FILE *ptrFile2 = NULL;
int KeyLen = 0;
char k_str1[] = "dfsa#@FGDS!dsaKJiewiu*#&*))__=22121kD()@#(*#@#@!DSKL909*(!#!@AA";
char k_str2[] = "*@#AdJJMLDML#SXAIO98390d&th2nfd%%u2j312&&dsjdAa";
char k_str3[] = "@!FS#@DSKkop()(290#0^^^2920-((__!#*$gf4SAddAA";
char Key[252];
strcpy(Key, HardWareID);
strcat(Key, k_str1);
strcat(Key, k_str2);
strcat(Key, k_str3);
strcat(Key, Public);
printf("* KEY: %s \n\n", Key);
BYTE *bKey = (BYTE*)Key;
KeyLen = strlen(Key);
HCRYPTPROV hCryptProv = NULL;
HCRYPTHASH hHash = NULL;
HCRYPTKEY hKey = NULL;
if (CryptAcquireContext(
&hCryptProv,
0,
NULL,
PROV_RSA_FULL,
0))
{
//printf("hCryptProv has been acquired.\n");
if (CryptCreateHash(
hCryptProv,
CALG_MD5,
0,
0,
&hHash))
{
//printf("An empty hash object has been created. \n");
if (CryptHashData(
hHash,
bKey,
KeyLen,
0))
{
//printf("CryptHashData succeed! \n");
if (CryptDeriveKey(
hCryptProv,
CALG_RC4,
hHash,
0x800000u,
&hKey))
{
//printf("CryptDeriveKey Succeed! \n");
BYTE *bBuffer = (BYTE*)malloc(sizeof(BYTE) * 1008);
if (bBuffer)
{
ptrFile1 = fopen(tmpFile, "rb");
ptrFile2 = fopen(OutPutFileName, "wb+");
int FileFlag = 0;
bool decrypt = TRUE;
while (TRUE)
{
DWORD pdDataLen = fread(bBuffer, 1, 0x3E8, ptrFile1);
if (ferror(ptrFile1))
{
printf("Original file error! \n");
break;
}
FileFlag = feof(ptrFile1);
if (decrypt)
{
CryptDecrypt(hKey, 0, FileFlag, 0, bBuffer, &pdDataLen);
count--;
if (count == 0)
decrypt = FALSE;
}
fwrite(bBuffer, 1, pdDataLen, ptrFile2);
if (ferror(ptrFile2))
{
printf("Decrypt file Error! \n");
break;
}
if (FileFlag)
{
printf("*** Decrypt Success! ***\n");
break;
}
}
fclose(ptrFile1);
fclose(ptrFile2);
}
}
else
{
printf("CryptDeriveKey Error! \n");
}
}
else
{
printf("CryptHashData Error! \n");
}
}
else
{
printf("Error on CryptCreateHash! \n");
}
}
else
{
printf("CryptAcquireContext function Error!");
}
return 0;
}
PS:附件中包含解密程序的源码,对应病毒样本。(点击阅读原文下载)
Having fun!
看雪ID:逆向实习生
bbs.pediy.com/user-813298
本文由看雪论坛 逆向实习生 原创
转载请注明来自看雪社区
热门技术文章推荐: